[TOC]
JWT 验证
1. 安装包
Microsoft.AspNetCore.Authentication.JwtBearer System.IdentityModel.Tokens.Jwt
注意版本
2. 配置 appsettings.json
json
"Jwt": {
"Key": "your-very-long-secret-key-at-least-32-characters",
"Issuer": "my-dev-app",
"Audience": "my-dev-api",
"ExpireMinutes": 60
},ExpireMinutes: 分钟的意思 Key :一定要32位数以上
3. 注册 JWT 认证服务(Program.cs要写的)
C
#region jwt
// 读取 JWT 配置
var jwtKey = builder.Configuration["Jwt:Key"];
var jwtIssuer = builder.Configuration["Jwt:Issuer"];
var jwtAudience = builder.Configuration["Jwt:Audience"];
// 添加认证服务
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = jwtIssuer,
ValidAudience = jwtAudience,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtKey))
};
});
builder.Services.AddAuthorization(); // 添加授权服务
#endregion注意以上代码要在 var app = builder.Build(); 之前
C
// 添加中间件(顺序重要)
app.UseAuthentication(); // 认证中间件
app.UseAuthorization(); // 授权中间件4. 生成 JWT 的辅助类
C
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
public static class JwtHelper
{
public static string GenerateToken(IConfiguration config, string userId, string username, IEnumerable<string> roles)
{
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(config["Jwt:Key"]));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var claims = new List<Claim>
{
new Claim(JwtRegisteredClaimNames.Sub, userId),
new Claim(ClaimTypes.Name, username),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
};
// 添加角色(可多个)
foreach (var role in roles)
{
claims.Add(new Claim(ClaimTypes.Role, role));
}
var token = new JwtSecurityToken(
issuer: config["Jwt:Issuer"],
audience: config["Jwt:Audience"],
claims: claims,
expires: DateTime.UtcNow.AddMinutes(double.Parse(config["Jwt:ExpireMinutes"])),
signingCredentials: creds
);
return new JwtSecurityTokenHandler().WriteToken(token);
}
}5. 示例
C
[ApiController]
[Route("api/[controller]")]
public class AuthController : ControllerBase
{
private readonly IConfiguration _config;
public AuthController(IConfiguration config)
{
_config = config;
}
[HttpPost("login")]
public IActionResult Login([FromBody] LoginRequest request)
{
// 模拟用户验证(实际应从数据库查询)
if (request.Username == "admin" && request.Password == "123")
{
var token = JwtHelper.GenerateToken(_config, "1", request.Username, new[] { "Admin" });
return Ok(new { token });
}
return Unauthorized("用户名或密码错误");
}
}
public class LoginRequest
{
public string Username { get; set; }
public string Password { get; set; }
}其他需要验证的方法加上
C
[Authorize(Roles = "Admin")]6. jwt 对应的函数 常用声明类型与 JWT 对应关系
| 用途 | JWT 声明 | .NET ClaimType | 获取方法 |
|---|---|---|---|
| 用户 ID | sub | ClaimTypes.NameIdentifier | User.FindFirstValue(ClaimTypes.NameIdentifier) |
| 用户名 | unique_name 或自定义 | ClaimTypes.Name | User.Identity.Name 或 User.FindFirstValue(ClaimTypes.Name) |
| 角色 | role | ClaimTypes.Role | User.FindAll(ClaimTypes.Role) |
| 邮箱 | email | ClaimTypes.Email | User.FindFirstValue(ClaimTypes.Email) |
| JWT ID | jti | JwtRegisteredClaimNames.Jti | User.FindFirstValue(JwtRegisteredClaimNames.Jti) |
7. 获取当前登录用户信息
C
using System.Security.Claims;
namespace demo1.Uitl.JWT
{
public static class ClaimsPrincipalExtensions
{
/// <summary>
/// 获取当前登录用户id
/// </summary>
/// <param name="user"></param>
/// <returns></returns>
public static long GetUserId(this ClaimsPrincipal user)
{
var id = user.FindFirstValue(ClaimTypes.NameIdentifier);
return long.TryParse(id, out long result) ? result : 0;
}
/// <summary>
/// 获取当前登录用户
/// </summary>
/// <param name="user"></param>
/// <returns></returns>
public static string GetUserName(this ClaimsPrincipal user)
{
return user.Identity?.Name ?? user.FindFirstValue(ClaimTypes.Name);
}
/// <summary>
/// 判断用户是否权限
/// var claims = new List<Claim>
//{
// // ... 其他声明
// new Claim("permission", "article:delete"),
// new Claim("permission", "article:edit")
//};
/// </summary>
/// <param name="user"></param>
/// <param name="permission"></param>
/// <returns></returns>
public static bool HasPermission(this ClaimsPrincipal user, string permission)
{
return user.HasClaim(c => c.Type == "permission" && c.Value == permission);
}
}
}使用案例
C
User